package cn.hdu.liang.ch05;

import java.util.Map;
import java.util.concurrent.*;

/**
 * 基于FutureTask的Memoizing包装器
 */
public class Memoizer3<A, V> implements Computable<A, V> {
    private final Map<A, Future<V>> cache = new ConcurrentHashMap<>();
    private final Computable<A, V> c;

    public Memoizer3(Computable<A, V> c) {
        this.c = c;
    }

    public V compute(final A arg) throws InterruptedException {
        Future<V> f = cache.get(arg);
        if(f == null) {
            FutureTask<V> ft = new FutureTask<>(() -> c.compute(arg));
            f = ft;
            cache.put(arg, ft);
            ft.run(); // call to c.compute happens here
        }
        try {
            return f.get();
        } catch(ExecutionException e) {
            throw LaunderThrowable.launderThrowable(e.getCause());
        }
    }
}